// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System.Globalization;
using System.Text;
using JetBrains.Annotations;
using SnapObjects.Commons;

namespace SnapObjects.Data.Odbc
{
    internal abstract class OdbcUpdateSqlGeneratorBase : UpdateSqlGenerator
    {
        private readonly ITypeMapper _mapper;

        public OdbcUpdateSqlGeneratorBase(
            OdbcSqlGenerationHelperBase odbcSqlGenerationHelper, ITypeMapper mapper)
            : base(odbcSqlGenerationHelper)
        {
            _mapper = mapper;
        }

        protected override ResultSetMapping AppendSelectAffectedCountSql(
            StringBuilder sqlStringBuilder, string name, string schema, int sqlPosition)
        {
            sqlStringBuilder
                .Append("SELECT @@ROWCOUNT")
                .Append(this.SqlGenerationHelper.StatementTerminator).AppendLine()
                .AppendLine();

            return ResultSetMapping.RowCountAndLastInResultSet;
        }

        public override void AppendBatchHeader(StringBuilder sqlStringBuilder)
        {
            sqlStringBuilder
                           .Append("SET NOCOUNT ON")
                           .Append(this.SqlGenerationHelper.StatementTerminator).AppendLine();
        }

        protected override void AppendIdentityWhereCondition(StringBuilder sqlStringBuilder,
            ColumnModification columnModification)
        {
            this.SqlGenerationHelper.DelimitIdentifier(sqlStringBuilder,
                columnModification.MappedColumn);
            sqlStringBuilder.Append(" = ");

            sqlStringBuilder.Append("@@identity");
        }

        protected override void AppendRowsAffectedWhereCondition(StringBuilder sqlStringBuilder,
            int expectedRowsAffected)
        {
            sqlStringBuilder
                           .Append("@@ROWCOUNT = ")
                           .Append(expectedRowsAffected.ToString(CultureInfo.InvariantCulture));
        }

        protected override void AppendWhereAffectedCondition(
            [NotNull] StringBuilder sqlStringBuilder,
            [NotNull] ColumnModification columnModification,
            bool useOriginalValue)
        {
            Check.NotNull(sqlStringBuilder, nameof(sqlStringBuilder));
            Check.NotNull(columnModification, nameof(columnModification));

            this.SqlGenerationHelper.DelimitIdentifier(sqlStringBuilder, columnModification.MappedColumn);

            var parameterValue = useOriginalValue
                ? columnModification.OriginalValue
                : columnModification.CurrentValue;

            if (parameterValue == null)
            {
                sqlStringBuilder.Append(" IS NULL");
            }
            else
            {
                sqlStringBuilder.Append(" = ");
                var mapping = _mapper.FindMapping(columnModification.Property.DataType);

                sqlStringBuilder.Append(mapping.GenerateSqlLiteral(parameterValue));
            }
        }
    }
}
